package cn.zebra.dev.member.module.member.controller;

import cn.zebra.dev.common.constant.SysConstant;
import cn.zebra.dev.common.restful.Result;
import cn.zebra.dev.common.utils.NumberUtils;
import cn.zebra.dev.common.utils.SecurityUtils;
import cn.zebra.dev.common.utils.StrUtils;
import cn.zebra.dev.feign.service.SmsService;
import cn.zebra.dev.member.module.login.service.SecurityMemberService;
import cn.zebra.dev.member.module.member.dto.MemberInfoDTO;
import cn.zebra.dev.base.module.member.entity.BaseMember;
import cn.zebra.dev.member.module.member.entity.MemberEntity;
import cn.zebra.dev.member.module.member.service.MemberService;
import cn.zebra.dev.member.module.member.vo.*;
import cn.zebra.dev.member.module.security.entity.MemberDetailsEntity;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;

/**
 * @author runnable@sina.cn
 */
@Api(tags = "用户服务")
@RestController
public class MemberController {

    @Autowired
    private SecurityMemberService securityMemberService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private MemberService memberService;

    @Autowired
    private SmsService smsService;

    @GetMapping("/info")
    @ApiOperation("用户信息")
    public Result<MemberInfoDTO> info() {
        BaseMember member = securityMemberService.getBaseMember();
        MemberInfoDTO dto = new MemberInfoDTO();
        Long memberId = member.getId();
        dto.setId(memberId);
        dto.setMemberName(member.getMemberName());
        dto.setMemberHeadImg(member.getMemberHeadImg());
        dto.setSex(member.getSex());
        dto.setEmail(member.getEmail());
        dto.setDay(member.getBirthdayDay());
        dto.setMonth(member.getBirthdayMonth());
        dto.setYear(member.getBirthdayYear());
        return Result.success(dto);
    }

    @GetMapping("/getPhone")
    @ApiOperation("获取自己手机号 中间四位替换为*")
    public Result getPhone() {
        String phone = securityMemberService.getMemberPhone();
        StringBuilder builder = new StringBuilder(phone).replace(3, 7, "****");
        return Result.success(builder);
    }

    @PostMapping("/editPhone")
    @ApiOperation("修改手机号")
    public Result editPhone(@Valid @RequestBody MemberEditPhoneVO param) {
        String key = SysConstant.PHONE_CHANGE_CODE + securityMemberService.getMemberPhone();
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        String code = operations.get(key);
        if (StrUtils.isBlank(code)) {
            return Result.error("您的验证码已过期!请重新发送");
        }
        if (!param.getCode().equals(code.replace("\"", ""))) {
            return Result.error("验证码不正确!");
        }
        operations.getOperations().delete(key);
        String newPhone = param.getNewPhone();
        if (memberService.selectOne("phone={0}", newPhone) != null) {
            return Result.error("该手机号已存在!");
        }
        BaseMember member = securityMemberService.getBaseMember();
        if (memberService.updateMemberPhone(member.getId(), newPhone)) {
            ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
            member.setPhone(newPhone);
            valueOperations.set(SysConstant.MEMBER + member.getPhone(), JSON.toJSONString(new MemberDetailsEntity(member)));
            return Result.success("修改成功!");
        }

        return Result.error("修改失败 请稍后再试!");
    }

    @GetMapping("/editPhoneCode")
    @ApiOperation("修改手机号验证码")
    public Result editPhoneCode() {
        String phone = securityMemberService.getMemberPhone();
        String key = SysConstant.PHONE_CHANGE_CODE + phone;
        Map<String, Object> sendMap = new HashMap<>(5);
        Integer code = NumberUtils.getRandom(100000, 999999);
        sendMap.put("key", key);
        sendMap.put("phone", phone);
        Integer minute = 3;
        sendMap.put("content", String.format("【%s】您的修改手机号验证码为：%s。%s分钟内有效，请勿告诉他人。", "TMT", code, minute));
        sendMap.put("code", code);
        sendMap.put("minute", minute);
        return smsService.sendContent(sendMap);
    }

    @GetMapping("/isSecondaryPassword")
    @ApiOperation("是否需要设置资金密码")
    public Result isSecondaryPassword() {
        BaseMember member = securityMemberService.getBaseMember();
        return Result.success(StrUtils.isBlank(member.getSecondaryPassword()));
    }

    @PostMapping("/setSecondaryPassword")
    @ApiOperation("设置资金密码")
    public Result setSecondaryPassword(@Valid @RequestBody MemberSetSecondaryPasswordVO param) {
        BaseMember member = securityMemberService.getBaseMember();
        if (StrUtils.isNotBlank(member.getSecondaryPassword())) {
            return Result.error("您已设置了资金密码 如需修改资金请在修改页修改资金密码!");
        }
        //盐
        String salt = SecurityUtils.getMd5(StrUtils.getUUID());
        //生成密码
        String password = SecurityUtils.getMd5(salt + param.getPasswoed());
        if (memberService.updateMemberSecondaryPassword(member.getId(), salt, password)) {
            member.setSecondarySalt(salt);
            member.setSecondaryPassword(password);
            ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
            valueOperations.set(SysConstant.MEMBER + member.getPhone(), JSON.toJSONString(new MemberDetailsEntity(member)));
            return Result.success("设置成功!");
        }

        return Result.error("设置密码失败 请稍后再试!");
    }

    @PostMapping("/resetSecondaryPassword")
    @ApiOperation("修改资金密码")
    public Result resetSecondaryPassword(@RequestBody MemberPasswordVO param) {
        BaseMember member = securityMemberService.getBaseMember();
        String password = member.getSecondaryPassword();
        String salt = member.getSecondarySalt();
        String oldPassword = param.getOldPassword();
        if (!password.equals(SecurityUtils.getMd5(salt + oldPassword))) {
            return Result.error("旧密码输入有误!");
        }
        String newPassword = param.getNewPassword();
        if (oldPassword.equals(newPassword)) {
            return Result.error("旧密码与新密码一致!");
        }

        newPassword = SecurityUtils.getMd5(salt + newPassword);
        if (memberService.updateMemberSecondaryPassword(member.getId(), newPassword)) {
            ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
            member.setSecondaryPassword(newPassword);
            valueOperations.set(SysConstant.MEMBER + member.getPhone(), JSON.toJSONString(new MemberDetailsEntity(member)));
            return Result.success("修改成功!");
        }

        return Result.error("修改密码失败 请稍后再试!");
    }

    @PostMapping("/updateMember")
    @ApiOperation("修改用户信息")
    public Result updateMember(@Valid @RequestBody MemberUpdateMemberVO vo) {
        BaseMember member = securityMemberService.getBaseMember();
        MemberEntity updateEntity = new MemberEntity();
        updateEntity.setMemberHeadImg(vo.getImageUrl());
        updateEntity.setSex(vo.getSex());
        updateEntity.setMemberName(vo.getMemberName());
        LocalDate birthday = vo.getBirthday();
        if (birthday.compareTo(LocalDate.now()) > 0) {
            return Result.error("生日不能大于今天，请选择正确的日期!");
        }else{
            updateEntity.setBirthdayYear(Integer.valueOf(vo.getBirthday().getYear()));
            updateEntity.setBirthdayMonth(Integer.valueOf(vo.getBirthday().getMonthValue()));
            updateEntity.setBirthdayDay(Integer.valueOf(vo.getBirthday().getDayOfMonth()));
        }
        if (!memberService.update(updateEntity, "id = {0}", member.getId())) {
            return Result.error("修改用户信息失败!");
        }
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        member.setMemberHeadImg(vo.getImageUrl());
        member.setSex(vo.getSex());
        member.setMemberName(vo.getMemberName());
        member.setBirthdayYear(vo.getBirthday().getYear());
        member.setBirthdayMonth(vo.getBirthday().getMonthValue());
        member.setBirthdayDay(vo.getBirthday().getDayOfMonth());
        valueOperations.set(SysConstant.MEMBER + member.getPhone(), JSON.toJSONString(new MemberDetailsEntity(member)));
        return Result.success();
    }

    @GetMapping("/getMemberHeadImg")
    @ApiOperation("获取自己个人头像")
    public Result getMemberHeadImg() {
        return Result.success(securityMemberService.getMemberPhoto());
    }

    @GetMapping("/getMemberName")
    @ApiOperation("获取昵称")
    public Result getMemberName() {
        return Result.success(securityMemberService.getMemberName());
    }

    @GetMapping("/getMemberSex")
    @ApiOperation("获取用户性别")
    public Result getMemberSex() {
        return Result.success(securityMemberService.getBaseMember().getSex());
    }

}
